home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_std / array3.e < prev    next >
Text File  |  2000-03-25  |  12KB  |  424 lines

  1. -- This file is  free  software, which  comes  along  with  SmallEiffel. This
  2. -- software  is  distributed  in the hope that it will be useful, but WITHOUT 
  3. -- ANY  WARRANTY;  without  even  the  implied warranty of MERCHANTABILITY or
  4. -- FITNESS  FOR A PARTICULAR PURPOSE. You can modify it as you want, provided
  5. -- this header is kept unaltered, and a notification of the changes is added.
  6. -- You  are  allowed  to  redistribute  it and sell it, alone or as a part of 
  7. -- another product.
  8. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  9. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  10. --                       http://SmallEiffel.loria.fr
  11. --
  12. class ARRAY3[E]
  13.    --
  14.    -- General prurpose, resizable, three dimensional array.
  15.    --
  16.    -- Initially written by Jean-Philippe Caillaut in Mai 1999
  17.    --
  18.  
  19. inherit COLLECTION3[E];
  20.    
  21. creation 
  22.    make, copy, from_collection3, from_collection, from_model
  23.  
  24. feature 
  25.  
  26.    lower1, lower2, lower3, upper1, upper2, upper3: INTEGER;
  27.  
  28.    count1, count2, count3, count: INTEGER;
  29.    
  30. feature {ARRAY3}
  31.    
  32.    storage: NATIVE_ARRAY[E];
  33.      -- To store elements line by line.
  34.    
  35.    capacity: INTEGER;
  36.      -- Number of elements in `storage'.
  37.    
  38. feature -- Creation / modification :
  39.    
  40.    make(line_min, line_max, column_min, column_max, depth_min, depth_max: INTEGER) is
  41.          -- Reset all bounds `line_minimum' / `line_maximum' / `column_minimum' 
  42.          -- `column_maximum' / `depth_min' and `depth_max' using arguments as
  43.          -- new values. All elements are set to the default value of type E.
  44.       require
  45.      line_min <= line_max;
  46.          column_min <= column_max;
  47.          depth_min <= depth_max
  48.       do
  49.      lower1 := line_min;
  50.      upper1 := line_max;
  51.      lower2 := column_min;
  52.      upper2 := column_max;
  53.          lower3 := depth_min;
  54.          upper3 := depth_max;
  55.      count1 := upper1 - lower1 + 1;
  56.      count2 := upper2 - lower2 + 1;
  57.      count3 := upper3 - lower3 + 1;
  58.      count := count1 * count2 * count3;
  59.      if capacity >= count then
  60.         storage.clear_all(count - 1);
  61.      else
  62.         capacity := count;
  63.         storage := storage.calloc(count);
  64.      end;
  65.       ensure
  66.      line_minimum = line_min;
  67.      line_maximum = line_max;
  68.      column_minimum = column_min;
  69.      column_maximum = column_max;
  70.          depth_minimum = depth_min;
  71.          depth_maximum = depth_max;        
  72.       end;
  73.    
  74.    from_collection3(model: COLLECTION3[like item]) is
  75.       local
  76.          i, j, k: INTEGER;
  77.       do
  78.      make(model.line_minimum,
  79.           model.line_maximum,
  80.           model.column_minimum,
  81.               model.column_maximum,
  82.               model.depth_minimum,
  83.               model.depth_maximum);
  84.      from
  85.         i := line_minimum;
  86.      until
  87.         i > line_maximum
  88.      loop
  89.         from
  90.            j := column_minimum;
  91.         until
  92.            j > column_maximum
  93.         loop
  94.                from
  95.                   k := depth_minimum;
  96.                until
  97.                   k > depth_maximum
  98.                loop
  99.                   put(model.item(i,j,k),i,j,k);
  100.                   k := k + 1;
  101.                end;
  102.               j := j + 1;
  103.         end;
  104.         i := i + 1;
  105.      end;
  106.       ensure then
  107.      lower1 = model.lower1;
  108.          lower2 = model.lower2;
  109.          lower3 = model.lower3;
  110.       end;
  111.    
  112.    from_collection(contents: COLLECTION[E];
  113.         line_min, line_max, column_min, column_max, depth_min, depth_max: INTEGER) is
  114.      --  Reset all bounds using `line_min', `line_max', `column_min',
  115.          --  `column_max', `depth_min', and `depth_max'.
  116.      --  Copy all elements of `contents', line by line into Current.
  117.       require
  118.      line_min <= line_max;
  119.      column_min <= column_max;      
  120.          depth_min <= depth_max;
  121.          contents.count = (line_max - line_min + 1) * (column_max - column_min + 1) * (depth_max - depth_min + 1)
  122.       local
  123.      i: INTEGER 
  124.       do
  125.          make(line_min,line_max,column_min,column_max,depth_min,depth_max)
  126.      from 
  127.         i := 0  
  128.      until
  129.         i >= count
  130.      loop
  131.         storage.put(contents.item(contents.lower + i),i);
  132.         i := i + 1; 
  133.      end
  134.       ensure
  135.      line_minimum = line_min;
  136.      line_maximum = line_max;
  137.      column_minimum = column_min;
  138.      column_maximum = column_max;
  139.          depth_minimum = depth_min;
  140.          depth_maximum = depth_max;        
  141.          count = contents.count
  142.       end
  143.  
  144.    from_model(model: COLLECTION[COLLECTION[COLLECTION[E]]]) is
  145.          -- The `model' is used to fill line by line the COLLECTION3.
  146.          -- Assume all sub-collections of have the same indexing.
  147.       local
  148.          line, column, depth: INTEGER;
  149.       do
  150.      make(model.lower,
  151.           model.upper,
  152.           model.first.lower,
  153.               model.first.upper,
  154.               model.first.first.lower,
  155.               model.first.first.upper);
  156.      from
  157.         line := model.lower;
  158.      until
  159.         line > model.upper
  160.      loop
  161.         from
  162.            column := model.first.lower
  163.         until
  164.            column > model.first.upper
  165.         loop
  166.                from
  167.                   depth := model.first.first.lower
  168.                until
  169.                   depth > model.first.first.upper
  170.                loop
  171.                   put(model.item(line).item(column).item(depth),line,column,depth);
  172.                   depth := depth + 1;
  173.                end;
  174.            column := column + 1;
  175.         end;
  176.         line := line + 1;
  177.      end;
  178.       ensure
  179.      line_minimum = model.lower;
  180.      line_maximum = model.upper;
  181.      column_minimum = model.first.lower;
  182.          column_maximum = model.first.upper;
  183.          depth_minimum = model.first.first.lower;
  184.          depth_maximum = model.first.first.upper
  185.       end;
  186.    
  187. feature -- Resizing :
  188.  
  189.    resize(line_min, line_max, column_min, column_max, depth_min, depth_max: INTEGER) is
  190.      -- Resize bounds of the Current array
  191.       require
  192.      line_max >= line_min;
  193.      column_max >= column_min;
  194.          depth_max >= depth_min;
  195.       local
  196.      tmp: like Current;
  197.          l, c, d: INTEGER;
  198.       do
  199.          !!tmp.make(line_min, line_max, column_min, column_max, depth_min, depth_max);
  200.          -- It may be possible to avoid this creation when :
  201.      --    new `capacity' <= old `capacity'
  202.      from
  203.         l := lower1;
  204.      until
  205.         l > line_maximum
  206.      loop
  207.         from
  208.            c := lower2;
  209.         until
  210.            c > column_maximum
  211.         loop
  212.                from
  213.                   d := lower3;
  214.                until
  215.                   d > depth_maximum
  216.                loop
  217.                   if tmp.valid_index(l,c,d) then
  218.                      tmp.put(item(l,c,d),l,c,d);
  219.                   end;
  220.                   d := d + 1;
  221.                end;
  222.            c := c + 1;
  223.         end;
  224.         l := l + 1;
  225.      end;
  226.      standard_copy(tmp);
  227.       ensure
  228.      line_minimum = line_min;
  229.      line_maximum = line_max;
  230.      column_minimum = column_min;
  231.      column_maximum = column_max;
  232.          depth_minimum = depth_min;
  233.          depth_maximum = depth_max
  234.       end;
  235.    
  236. feature -- Implementation of others feature from COLLECTION3 :
  237.    
  238.    item(line, column, depth: INTEGER): E is
  239.       do
  240.          Result := storage.item((line - lower1) * count2 * count3 + (column - lower2) * count3 + depth - lower3);
  241.       end;
  242.  
  243.    put(element: like item; line, column, depth: INTEGER) is
  244.       do
  245.          storage.put(element,(line - lower1) * count2 * count3 + (column - lower2) * count3 + depth - lower3);
  246.       end;
  247.    
  248.    force(x: like item; line, column, depth: INTEGER) is
  249.       require
  250.      true
  251.       do
  252.          if not valid_index(line,column,depth) then
  253.         resize(line.min(lower1),
  254.            line.max(upper1),
  255.            column.min(lower2),
  256.                    column.max(upper2),
  257.                    depth.min(lower3),
  258.                    depth.max(upper3));
  259.      end;
  260.          put(x,line,column,depth);
  261.       end;
  262.    
  263.    set_all_with(element: E) is
  264.       do
  265.      storage.set_all_with(element,count - 1);
  266.       end;
  267.    
  268.    replace_all(old_value, new_value: like item) is
  269.       do
  270.      storage.replace_all(old_value,new_value,count - 1);
  271.       end;
  272.      
  273.    fast_replace_all(old_value, new_value: like item) is
  274.       do
  275.      storage.fast_replace_all(old_value,new_value,count - 1);
  276.       end;
  277.      
  278.    sub_collection3(line_min, line_max, column_min, column_max, 
  279.                    depth_min, depth_max: INTEGER): like Current is
  280.       local
  281.          i, j, k, n: INTEGER;
  282.       do
  283.          !!Result.make(line_min,line_max,column_min,column_max,
  284.                        depth_min,depth_max);
  285.      from
  286.         i := line_min;
  287.         k := 0;
  288.      until
  289.         i > line_max
  290.      loop
  291.         from
  292.            j := column_min;
  293.         until
  294.            j > column_max
  295.         loop
  296.                from
  297.                   k := depth_min;
  298.                until
  299.                   k > depth_max
  300.                loop
  301.                   Result.storage.put(item(i,j,k),n);
  302.                   n := n + 1;
  303.                   k := k + 1;
  304.                end;
  305.                j := j + 1;
  306.         end;
  307.         i := i + 1;
  308.      end;
  309.       ensure
  310.      Result.lower1 = line_min; 
  311.      Result.lower2 = column_min; 
  312.          Result.lower3 = depth_min;
  313.      Result.upper1 = line_max;
  314.      Result.upper2 = column_max;
  315.          Result.upper3 = depth_max;
  316.       end;
  317.  
  318. feature --  Looking and comparison :
  319.  
  320.    nb_occurrences(elt: E): INTEGER is
  321.      -- Number of occurrences using `equal'.
  322.          -- See also `fast_nb_occurrences' to choose
  323.      -- the apropriate one.
  324.       do
  325.      Result := storage.nb_occurrences(elt,count - 1);
  326.       end;
  327.    
  328.    fast_nb_occurrences(elt: E): INTEGER is
  329.      -- Number of occurrences using `='.
  330.       do
  331.      Result := storage.fast_nb_occurrences(elt,count - 1);
  332.       end;
  333.  
  334.    has(x: like item): BOOLEAN is
  335.      -- Search if a element x is in the array using `equal'.
  336.          -- See also `fast_has' to choose the apropriate one.
  337.       do
  338.      Result := storage.index_of(x,count - 1) <= count - 1;
  339.       end;
  340.    
  341.    fast_has(x: like item): BOOLEAN is
  342.      --  Search if a element x is in the array using `='.
  343.       do
  344.      Result := storage.fast_index_of(x,count - 1) <= count -1;
  345.       end;
  346.    
  347.    all_default: BOOLEAN is
  348.       do
  349.      result := storage.all_default(count - 1);
  350.       end;
  351.  
  352.    swap(line1, column1, depth1, line2, column2, depth2 : INTEGER) is
  353.       local
  354.      tmp: like item;
  355.          index1, index2: INTEGER;
  356.       do
  357.          index1 := (line1 - lower1) * count2 * count3 + (column1 - lower2) * count3 + depth1 - lower3;
  358.          index2 := (line2 - lower1) * count2 * count3 + (column2 - lower2) * count3 + depth2 - lower3;
  359.      tmp := storage.item(index1);
  360.      storage.put(storage.item(index2),index1);
  361.      storage.put(tmp,index2);
  362.       end
  363.  
  364.    copy(other: like Current) is
  365.       do
  366.      lower1 := other.lower1;
  367.      upper1 := other.upper1;
  368.      lower2 := other.lower2;
  369.      upper2 := other.upper2;
  370.          lower3 := other.lower3;
  371.          upper3 := other.upper3;
  372.      count := other.count;
  373.      count1 := other.count1;
  374.      count2 := other.count2;
  375.      count3 := other.count3;
  376.      if capacity < count then
  377.         capacity := count;
  378.         storage := storage.calloc(count);
  379.      end;
  380.      storage.copy_from(other.storage, count - 1);
  381.       end;
  382.    
  383.    is_equal(other: like Current): BOOLEAN is
  384.       do
  385.      if other = Current then
  386.         Result := true;
  387.      elseif lower1 /= other.lower1 then
  388.      elseif lower2 /= other.lower2 then
  389.          elseif lower3 /= other.lower3 then
  390.          elseif upper1 /= other.upper1 then
  391.          elseif upper2 /= other.upper2 then
  392.          elseif upper3 /= other.upper3 then
  393.      else
  394.         Result := storage.memcmp(other.storage,count);
  395.      end;
  396.       end;
  397.  
  398.    same_as(other: COLLECTION3[E]): BOOLEAN is
  399.       do
  400.          Result := other.same_as_array3(Current);
  401.       end;
  402.  
  403. feature {COLLECTION3}
  404.  
  405.    same_as_array3(other: ARRAY3[E]): BOOLEAN is
  406.       do
  407.      Result := standard_same_as(other);
  408.       end;
  409.  
  410.    same_as_fixed_array3(other: FIXED_ARRAY3[E]): BOOLEAN is
  411.       do
  412.      Result := standard_same_as(other);
  413.       end;
  414.  
  415. invariant
  416.  
  417.    count1 = upper1 - lower1 + 1;
  418.    count2 = upper2 - lower2 + 1;
  419.    count3 = upper3 - lower3 + 1;
  420.  
  421.    capacity >= count
  422.  
  423. end -- ARRAY3[E]
  424.